home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
071-080
/
amok75
/
oberon3.0
/
o3demo2.lzh
/
Beispiele
/
Amok.mod
< prev
next >
Wrap
Text File
|
1992-08-22
|
8KB
|
340 lines
(*---------------------------------------------------------------------------
Kleines 3D-Demo
An einem Sonntag Vor(!)mittag geschrieben.
(Es ist doch etwas aus meiner 3D-Grafik-Zeit hängengeblieben)
--- Fridtjof.
:Program. Amok
:Contents. Kleines 3D-Demo
:Version. V1.0, Dezember 89, Fridtjof Siebert
:Version. V1.1, Juni 90, Fridtjof Siebert, Now uses Array-Constants
:Author. Fridtjof Siebert
:Address. Nobileweg 67, D-7000 Suttgart 40
:CopyRight. PD
:Language. OBERON
:Compiler. AMOK OBORON Compiler, V0.2 beta
---------------------------------------------------------------------------*)
MODULE Amok;
(* $OvflChk- $RangeChk- $StackChk- $NilChk- $ReturnChk- $CaseChk- *)
IMPORT g := Graphics,
I := Intuition,
e := Exec,
d := Dos;
CONST
PointCnt = 19;
LineCnt = 14;
Auge = 200;
TYPE
Point = ARRAY 3 OF LONGINT; (* x, y und z Koordinate *)
Point2D= STRUCT x,y: INTEGER; (* Koordinaten auf Bildschirm *)
in: BOOLEAN; (* innerhalb des Schirms? *)
dummy: INTEGER; (* nur, damit size=2^3 (speed)*)
END;
SPoint = ARRAY 3 OF INTEGER;
Line = ARRAY 2 OF INTEGER; (* Start- und Endpunkt *)
Matrix = ARRAY 3, 3 OF LONGINT; (* Abbildematrix (Festpunktintegers) *)
PArray = ARRAY PointCnt OF Point;
SPArray = ARRAY PointCnt OF SPoint;
LArray = ARRAY LineCnt OF Line;
FourMatrices = ARRAY 4 OF Matrix;
VAR
CurMat: Matrix;
Points: PArray;
AbbPoints: ARRAY PointCnt OF Point2D; (* Abgebildete Punkte *)
count, c2: INTEGER; (* Zählt Abbildungen *)
ns: I.NewScreen;
nw: I.NewWindow;
screen: I.ScreenPtr;
window: I.WindowPtr;
rp1,rp2: g.RastPortPtr;
Width : INTEGER;
Height : INTEGER;
MitteX : INTEGER;
MitteY : INTEGER;
BitMap: ARRAY 3 OF g.BitMapPtr; (* 3-Fach gepuffert (Troublebuffering) *)
troubleBuf: INTEGER; (* aktive BitMap *)
AugeX: INTEGER; (* Augenposition *)
AugeY: INTEGER;
CONST
SPoints = SPArray( -140, 40, 40, - 90,- 40, 40,
- 90, 40, 40, -120, 10, 40,
- 90, 10, 40, - 70, 40, 40,
- 70,- 40, 40, - 40, 0, 40,
- 10,- 40, 40, - 10, 40, 40,
10, 40, 40, 50, 40, 40,
50,- 40, 40, 10,- 40, 40,
70,- 40, 40, 70, 40, 40,
120,- 40, 40, 90, 10, 40,
120, 40, 40);
Lines = LArray( 0, 1, 1, 2,
3, 4, 5, 6,
6, 7, 7, 8,
8, 9, 10,11,
11,12, 12,13,
13,10, 14,15,
15,16, 17,18);
mats = FourMatrices(7FFFH, 0, 0, (* Einheitsmatrix *)
0,7FFFH, 0,
0, 0,7FFFH,
32642, 0, 2856, (* Drehung um Y (5°) *)
0,7FFFH, 0,
-2856, 0,32642,
32642, 2856, 0, (* Drehung um Z (5°) *)
-2856,32642, 0,
0, 0,7FFFH,
7FFFH, 0, 0, (* Drehung um X (5°) *)
0,32642, 2856,
0,-2856,32642);
(*-------------------------------------------------------------------------*)
PROCEDURE MulVecMat(VAR E,V: Point; VAR M: Matrix);
(* E := V * M *)
VAR
i: INTEGER;
BEGIN
i := 0;
REPEAT
E[i] := ASH( M[i,0]*V[0] + M[i,1]*V[1] + M[i,2]*V[2], -15);
INC(i);
UNTIL i=3;
END MulVecMat;
PROCEDURE MulMat(VAR M0,M1: Matrix);
(* M0 := M0 * M1 *)
VAR
i,j: INTEGER;
M,N: Matrix;
BEGIN
M := M1; N := M0; i := 0;
REPEAT
j := 0;
REPEAT
M0[i,j] := ASH( M[0,j]*N[i,0] + M[1,j]*N[i,1] + M[2,j]*N[i,2] ,-15);
INC(j);
UNTIL j=3;
INC(i);
UNTIL i=3;
END MulMat;
(*-------------------------------------------------------------------------*)
PROCEDURE Abbilden;
VAR
c: INTEGER;
a: Point2D;
AbbPnt: Point;
PROCEDURE GetAuge(c,mc: INTEGER): INTEGER;
VAR Auge: INTEGER;
BEGIN
Auge := c-mc;
IF Auge<-mc THEN RETURN -mc
ELSIF Auge> mc THEN RETURN mc
ELSE RETURN Auge END;
END GetAuge;
BEGIN
AugeX := GetAuge(screen.mouseX,MitteX);
AugeY := GetAuge(screen.mouseY,MitteY);
c := 0;
WHILE c<PointCnt DO
MulVecMat(AbbPnt,Points[c],CurMat);
a.x := SHORT(Auge*(AbbPnt[0]-AugeX) DIV (Auge - AbbPnt[2])) + MitteX + AugeX;
a.y := SHORT(Auge*(AbbPnt[1]-AugeY) DIV (Auge - AbbPnt[2])) + MitteY + AugeY;
a.in := (a.x>=0) AND (a.x<Width) AND (a.y>=0) AND (a.y<Height);
AbbPoints[c] := a;
INC(c);
END;
END Abbilden;
PROCEDURE Zeichnen;
VAR
c,i: INTEGER;
a,b: Point2D;
rp: g.RastPortPtr;
BEGIN
screen.viewPort.rasInfo.bitMap := BitMap[troubleBuf];
INC(troubleBuf); IF troubleBuf=3 THEN troubleBuf := 0 END;
rp1.bitMap := BitMap[troubleBuf];
rp2.bitMap := BitMap[troubleBuf];
I.MakeScreen(screen);
(* Achtung: Graphics.MrgCop() stürzt, wenn es von verschiedenen Tasks
gleichzeitig gerufen wird. Deshalb mach ich das so: *)
e.Forbid();
g.MrgCop(I.ViewAddress());
e.Permit();
g.SetAPen(rp1,0);
g.RectFill(rp1,0,0,Width-1,Height-1);
g.SetAPen(rp1,1);
g.SetAPen(rp2,1);
c := 0;
WHILE c<LineCnt DO
a := AbbPoints[Lines[c,0]];
b := AbbPoints[Lines[c,1]];
rp := rp2;
IF a.in AND b.in THEN rp := rp1 END;
g.Move(rp,a.x,a.y);
g.Draw(rp,b.x,b.y);
INC(c);
END;
END Zeichnen;
(*-------------------------------------------------------------------------*)
PROCEDURE OpenScreen;
VAR
c: INTEGER;
BEGIN
Width := g.gfx.normalDisplayColumns DIV 32 * 16;
Height := g.gfx.normalDisplayRows;
MitteX := Width DIV 2;
MitteY := Height DIV 2;
c := 0;
WHILE c<3 DO
NEW(BitMap[c]);
g.InitBitMap(BitMap[c]^,1,Width,Height);
BitMap[c].planes[0] := g.AllocRaster(Width,Height);
IF g.gfx.libNode.version>=36 THEN
g.BltClear(BitMap[c].planes[0],BitMap[c].bytesPerRow+10000H*BitMap[c].rows,LONGSET{1});
ELSE
g.BltClear(BitMap[c].planes[0],BitMap[c].bytesPerRow*BitMap[c].rows,LONGSET{});
END;
IF BitMap[c].planes[0]=NIL THEN HALT(0) END;
INC(c);
END;
troubleBuf := 0;
ns.width := Width;
ns.height := Height;
ns.depth := 1;
ns.type := I.customScreen + {I.customBitMap};
ns.customBitMap:= BitMap[0];
screen := I.OpenScreen(ns);
IF screen=NIL THEN HALT(0) END;
rp1 := I.ScreenToRastPort(screen);
nw.width := screen.width;
nw.height := screen.height;
nw.idcmpFlags := LONGSET{I.closeWindow};
nw.flags := LONGSET{I.windowClose,I.borderless};
nw.screen := screen;
nw.type := I.customScreen;
window := I.OpenWindow(nw);
IF window=NIL THEN HALT(0) END;
rp2 := window.rPort;
END OpenScreen;
(*-------------------------------------------------------------------------*)
BEGIN
OpenScreen;
count := 0;
REPEAT
c2 := 0;
REPEAT
Points[count,c2] := SPoints[count,c2];
INC(c2);
UNTIL c2=3;
INC(count);
UNTIL count=PointCnt;
count := 143; c2 := 0;
REPEAT
INC(count);
IF count=144 THEN count := 0;
CurMat := mats[0];
INC(c2); IF c2=4 THEN c2 := 0 END;
ELSE MulMat(CurMat,mats[c2]) END;
Abbilden;
Zeichnen;
UNTIL e.GetMsg(window.userPort)#NIL;
CLOSE
IF window#NIL THEN I.CloseWindow(window) END;
IF screen#NIL THEN I.OldCloseScreen(screen) END;
g.WaitBlit;
count := 0;
REPEAT
IF BitMap[count].planes[0]#NIL THEN g.FreeRaster(BitMap[count].planes[0],Width,Height) END;
INC(count);
UNTIL count=3;
END Amok.